package com.sylli.oeuf.server.db.sql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sylli.oeuf.server.exception.BasedException;
import com.sylli.oeuf.server.exception.ExceptionCause;

public class MySQLConnector {
	
	
	protected static Logger log = LoggerFactory.getLogger( "db.connector" );
	
	private static int callCount = 0;
	
	private String m_connectionString = "jdbc:mysql://devbox:3306/oeuf_db";		// this should be configurable
	
	private String m_username = "wheel";
	
	private String m_password = "wheel_password";
	
	private Connection m_conn;
	
	private static MySQLConnector instance = null;
	
	public static MySQLConnector getInstance() {
		if (instance == null) {
			synchronized (MySQLConnector.class) {
				if (instance == null) {
					instance = new MySQLConnector();
				}
			}
		}
		return instance;
	}
	
	public void setConnectionParameters(String connString, String username, String password) {
		m_connectionString = connString;
		m_username = username;
		m_password = password;
	}
	
	public String getConnectionString() {
		return m_connectionString;
	}
	
	public String getUsernameString() {
		return m_username;
	}
	
	public String getPasswordString() {
		return m_password;
	}
	
	private MySQLConnector() {
		callCount++;
		log.info("Created " + callCount);
		try {
			connectDatabase();
		} catch (BasedException e) {
			log.error("Exception during create a DatabaseManager" + e);
		}
	}
	
	public void reconnectDatabase() throws BasedException {
		try {
			disconnectDatabase();
		} catch (BasedException e) {
			log.error("database disconnect fail", e);
		}
		connectDatabase();
	}
	
	public void connectDatabase() throws BasedException {
		try {
			Class.forName ("com.mysql.jdbc.Driver").newInstance ();
			m_conn = DriverManager.getConnection (m_connectionString, m_username, m_password);
			log.info("Connect to database .. ok");
		} catch (Exception e) {
			log.error("Connect to database .. fail", e);
			throw new BasedException(ExceptionCause.DatabaseConnectionFail, e);
		}
	}
	
	public void disconnectDatabase() throws BasedException {
		try {
			if(m_conn == null) {
				return;
			}
			m_conn.close();
		} catch (SQLException e) {
			throw new BasedException(ExceptionCause.DatabaseTeardownFail, e);
		}
	}
	
	// helper
	
	public ResultSet sqlQuery(String _sql) throws SQLException {
		Statement st = m_conn.createStatement();
		ResultSet rs = st.executeQuery(_sql);
//		st.close();
		return rs;
	}
	
	public int sqlQueryUpdate(String _sql) throws SQLException {
		Statement st = m_conn.createStatement();
		int r = st.executeUpdate(_sql);
		st.close();
		return r;
	}
	
	// customizer
	
	public Connection getConnectionObject() {
		return m_conn;
	}
}
